<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  
  
  <link rel="shortcut icon" href="../../img/favicon.ico">
  <title>co.h - COROS Documentation</title>
  <link rel="stylesheet" href="../../css/theme.css" />
  <link rel="stylesheet" href="../../css/theme_extra.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" />
  
  <script>
    // Current page data
    var mkdocs_page_name = "co.h";
    var mkdocs_page_input_path = "reference/01_co.md";
    var mkdocs_page_url = null;
  </script>
  
  <script src="../../js/jquery-2.1.1.min.js" defer></script>
  <script src="../../js/modernizr-2.8.3.min.js" defer></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
  <script>hljs.initHighlightingOnLoad();</script> 
  
</head>

<body class="wy-body-for-nav" role="document">

  <div class="wy-grid-for-nav">

    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
    <div class="wy-side-scroll">
      <div class="wy-side-nav-search">
        <a href="../.." class="icon icon-home"> COROS Documentation</a>
        <div role="search">
  <form id ="rtd-search-form" class="wy-form" action="../../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" title="Type search term here" />
  </form>
</div>
      </div>

      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../..">Home</a>
                    </li>
                </ul>
                <p class="caption"><span class="caption-text">About</span></p>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../../COPYRIGHT/">Copyright</a>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../../LICENSE/">License</a>
                    </li>
                </ul>
                <p class="caption"><span class="caption-text">The Beginner's Guide to:</span></p>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../../tutorials/01_getting_started/">Getting Started</a>
                    </li>
                </ul>
                <p class="caption"><span class="caption-text">The Hitchker's Guide to:</span></p>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../../guides/01_coroutines/">Coroutines</a>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../../guides/02_event_queues/">Event Queues</a>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../../guides/03_components/">Components</a>
                    </li>
                </ul>
                <p class="caption"><span class="caption-text">The Technocrat's Guide to:</span></p>
                <ul class="current">
                    <li class="toctree-l1 current"><a class="reference internal current" href="./">co.h</a>
    <ul class="current">
    <li class="toctree-l2"><a class="reference internal" href="#data-types">Data types</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#api">API</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#co_t-co_createco_function-co_cb-size_t-stack_count-stack_t-stack_store">co_t co_create(co_function co_cb, size_t stack_count, stack_t *stack_store);</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#void-co_get_stashco_t-co">`void *co_get_stash(co_t co);</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#void-co_destroyco_t-co">void co_destroy(co_t *co);</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#void-co_resumeco_t-co-void-data">void *co_resume(co_t co, void *data);</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#void-co_startco_t-co-void-data">void *co_start(co_t co, void *data);</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#void-co_yieldvoid-data">void *co_yield(void *data);</a>
    </li>
        </ul>
    </li>
    </ul>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../02_evq/">evq.h</a>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../03_comp/">comp.h</a>
                    </li>
                </ul>
                <p class="caption"><span class="caption-text">The Technomancer's Guide to:</span></p>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../../architecture/01_coroutines/">Coroutines</a>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../../architecture/02_event_queues/">Event Queues</a>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../../architecture/03_porting/">Porting</a>
                    </li>
                </ul>
      </div>
    </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
        <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
        <a href="../..">COROS Documentation</a>
      </nav>

      
      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="breadcrumbs navigation">
  <ul class="wy-breadcrumbs">
    <li><a href="../..">Docs</a> &raquo;</li>
    
      
        
          <li>The Technocrat's Guide to: &raquo;</li>
        
      
    
    <li>co.h</li>
    <li class="wy-breadcrumbs-aside">
      
    </li>
  </ul>
  
  <hr/>
</div>
          <div role="main">
            <div class="section">
              
                <h1 id="the-technocrats-guide-to-coh">The Technocrat's Guide to <code>co.h</code></h1>
<p>CO is a small, simple, and fast implementation of Lua-style coroutines.  It has an API of four public functions (plus a fifth alias for clarity of communicating code purpose):</p>
<ul>
<li><code>co_create();</code></li>
<li><code>co_destroy();</code></li>
<li><code>co_resume();</code></li>
<li><code>co_yield();</code></li>
<li><code>co_start();</code></li>
</ul>
<p>Note that <code>co_start()</code> is just a synonym for <code>co_resume()</code>.</p>
<p>Coroutine functions can be called as regular functions as well as via Start/Resume.  Yielding during a normal function context is a null operation thus treating the coroutine function as if it were a normal function (at a miniscule cost in overhead).</p>
<p>This coroutine implementation is a strict parent/child variety.  Yielding within a coroutine always yields control to the routine that started/resumed it.  The parameter passed to <code>co_yield()</code> becomes the return value of the <code>co_resume()</code> call that started the child, and the data element passed to <code>co_resume()</code> becomes the return value of <code>co_yield()</code>.  This permits directed communication between parent and child.</p>
<h2 id="data-types">Data types</h2>
<ul>
<li><code>typedef uintptr_t stack_t;</code>           &ndash; The type of a single stack item.</li>
<li><code>typedef struct _co_t *co_t;</code>          &ndash; An opaque type serving as a coroutine handle.</li>
<li><code>typedef void (*co_function)(void *);</code> &ndash; The type of the coroutine implementation function.</li>
</ul>
<h2 id="api">API</h2>
<hr />
<h3 id="co_t-co_createco_function-co_cb-size_t-stack_count-stack_t-stack_store"><code>co_t co_create(co_function co_cb, size_t stack_count, stack_t *stack_store);</code></h3>
<p>Create a coroutine from a function and a provided stack area.</p>
<p><code>co_cb</code> (in)</p>
<blockquote>
<p>The function implementing the coroutine's operation.</p>
</blockquote>
<p><code>stack_count</code> (in)</p>
<blockquote>
<p>The number of items (<strong>not</strong> <strong><em>bytes</em></strong>!) the stack should hold.  An "item" is the natural size of a pushed value on the stack ... read the spec sheet (though it is usually <code>sizeof(uintptr_t)</code>).  Each core is different and confusion happens.  For the count, 256 is a good starting point for most things and you can scale up or down according to how deep your call tree is and how many parameters and local variables get involved.</p>
</blockquote>
<p><code>stack_store</code> (in)</p>
<blockquote>
<p>Pass <code>NULL</code> if you want dynamic assignment of stack space or a pointer to a properly-sized, properly-aligned array of values.</p>
</blockquote>
<p>This function returns a coroutine object used as a handle in subsequent operations, or <code>NULL</code> on failure.</p>
<hr />
<h3 id="void-co_get_stashco_t-co">`void *co_get_stash(co_t co);</h3>
<p>Extract the user-stashed data from the coroutine handle.  Coroutine creation has an optional user stash value that can be associated with it.  This permits other routines that know how to use it to extract it.  A possible use case for this is to store process information like names, priority, etc.  A scheduler could use the priority element to insert the coroutine into a heap and pull the top priority thread each time it schedules, for example, or a status routine could print an associated task name.</p>
<blockquote>
<p>Why store this in the coroutine instead of in application structures?  Because it permits far-flung components to extract useful information without binding them together tightly in shared data structures.  A protocol has to be agreed upon, in this case the actual structure behind the void*, but aside from that there is no other coupling this way, letting systems be more flexibly arranged and modified.</p>
</blockquote>
<p>This function returns whatever was passed into the <code>co_create()</code> call that made the <code>co_t</code>.</p>
<hr />
<h3 id="void-co_destroyco_t-co"><code>void co_destroy(co_t *co);</code></h3>
<p>Destroy a previously-created coroutine.</p>
<p>There is a small amount of dynamic data used in making a coroutine of approximately 8 bytes.  In cases where coroutines run to completion and exit it is necessary to call co_destroy() to reclaim this data.</p>
<p><code>co</code> (in)</p>
<blockquote>
<p>A <em>pointer</em> to the handle (returned by <code>co_create()</code>) of the coroutine object being cleaned up.</p>
</blockquote>
<p>Note: the <code>co</code> handle will be set to NULL to prevent its further use.</p>
<hr />
<h3 id="void-co_resumeco_t-co-void-data"><code>void *co_resume(co_t co, void *data);</code></h3>
<p>Transfer control to a coroutine, either starting an inactive coroutine or continuing from the last call to <code>co_yield()</code> inside of it.</p>
<p><code>co</code> (in)</p>
<blockquote>
<p>The handle of the coroutine being started or continued.</p>
</blockquote>
<p><code>data</code> (in)</p>
<blockquote>
<p>The data being passed to the coroutine.  If this is a newly-launched coroutine, it is the data parameter of the implementation function.  If this is a coroutine that has called <code>co_yield()</code> this is the <strong>return value</strong> of <code>co_yield()</code>.</p>
</blockquote>
<p><code>co_resume()</code> will return whatever data is passed to <code>co_yield()</code> by the coroutine, NULL otherwise (e.g. if the coroutine implementation function returns).</p>
<hr />
<h3 id="void-co_startco_t-co-void-data"><code>void *co_start(co_t co, void *data);</code></h3>
<p>This is nothing more than a synonym for <code>co_resume()</code> and operates in every possible way exactly the same.  It is supplied for semantic clarity only since although in the implementation "starting" and "continuing" a coroutine are the same thing, in the minds of people reading code they are separate operations.</p>
<hr />
<h3 id="void-co_yieldvoid-data"><code>void *co_yield(void *data);</code></h3>
<p>Yield control to the parent.  As a matter of safety, calling this from a situation where you are not running as a coroutine it is a null operation.  Otherwise it yields control to the parent thread of control.</p>
<p><code>data</code> (in)</p>
<blockquote>
<p>The value placed here is the return value of the <code>co_resume/start()</code> call that invoked the coroutine.</p>
</blockquote>
<p>The return value of <code>co_yield()</code> is the <code>data</code> parameter of the <code>co_resume/start()</code> call that reactivates the coroutine.</p>
<hr />
              
            </div>
          </div>
          <footer>
  
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="../02_evq/" class="btn btn-neutral float-right" title="evq.h">Next <span class="icon icon-circle-arrow-right"></span></a>
      
      
        <a href="../../guides/03_components/" class="btn btn-neutral" title="Components"><span class="icon icon-circle-arrow-left"></span> Previous</a>
      
    </div>
  

  <hr/>

  <div role="contentinfo">
    <!-- Copyright etc -->
    
  </div>

  Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
      
        </div>
      </div>

    </section>

  </div>

  <div class="rst-versions" role="note" aria-label="versions">
    <span class="rst-current-version" data-toggle="rst-current-version">
      
      
        <span><a href="../../guides/03_components/" style="color: #fcfcfc;">&laquo; Previous</a></span>
      
      
        <span style="margin-left: 15px"><a href="../02_evq/" style="color: #fcfcfc">Next &raquo;</a></span>
      
    </span>
</div>
    <script>var base_url = '../..';</script>
    <script src="../../js/theme.js" defer></script>
      <script src="../../search/main.js" defer></script>
    <script defer>
        window.onload = function () {
            SphinxRtdTheme.Navigation.enable(true);
        };
    </script>

</body>
</html>
